var private change_flag = OFF;

function private ModeChange()
{
	draw_mode = !draw_mode;
	change_flag = ON;
}

//
//	線を引く関数（なんじゃそりゃ）
//	boxmode:移動先のボックスを書くかどうかのフラグ
//
function private _MakeVector( org, boxmode )
{
	var	key, mat;
	var	temp, org_pos[2], pos[2];
	var	pick, draw_flag = ON;
	var	edge, i, j;

	draw_mode = OFF;
	change_flag = OFF;

	cur = Cursor();
	pick = cur;
	SelectBox( org_pos );
	edge = EdgeSelect();
	j = Edges( edge );
	input_flag = OFF;
	while( TRUE )
	{
		if( draw_flag == ON )
		{
			DrawLine( org, cur );
			if( boxmode == ON )
			{
				mat = move( UNIT_MATRIX, (Position( cur )- Position( org )));
				if( draw_mode == OFF )
					DrawBox( org_pos[0], org_pos[1], mat );
				else
				{
					for( i = 0; i< j; i++ )
					{
						EdgeGetVertex( edge, i, pos );
						DrawLine( pos[0]*mat, pos[1]*mat );
					}
				}
			}
		}
		key = WaitEvent();
		if( key )
			input_flag = ON;
		if( (( ShiftStat() & 1 ) == 1))
		{
			cur = Cursor();
			TrimCursor(org, MouseWindow());
			Cursor( cur );
		}
		else
			cur = Cursor();
		key = KeyCode();
		if( input_flag | key == INPUT_KEY )
			break;
		else if( key == ESC | quit_flag == TRUE )
			return -1;
		else if( key == BS )
			return -2;
		else if( key == 'c' )
			ModeChange();
		else
			temp = KeyProcess( key );
		if(((key!=0 ) & (key != INPUT_KEY))|( pick != Cursor())|(change_flag == ON))
		{
			draw_flag = ON;
			DrawLine( pick, org );
			if( boxmode == ON )
			{
				mat = move( UNIT_MATRIX, ( Position( pick ) - Position( org )));
				if( draw_mode == change_flag )
					DrawBox( org_pos[0], org_pos[1], mat );
				else
				{
					for( i = 0; i< j; i++ )
					{
						EdgeGetVertex( edge, i, pos );
						DrawLine( pos[0]*mat, pos[1]*mat );
					}
				}
			}
		}
		else
			draw_flag = OFF;
		pick = Cursor();
		change_flag = OFF;
		input_flag = OFF;
	}
	return 0;
}

//
//	平行移動&コピー
//
function CopyMovePolygons( flag )
{
	var	org, temp;
	var	vect;
	var	mat, move_vec[3];

	if ( SelectPolygons() == 0 )
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg3 );
		return ;
	}

	PushMenu();
	Status_org = Status_title;
	ClearStatus();
	if( flag == ON )
	{
		MenuPosition( Menu( " 動作設定(&S)",
			"詳細表示	C",	ModeChange, CheckMode,
			"--------",		SEPARATE_MENU,
			"複写中止	ESC",	MenuQuit
			), Menu_Title );
		Status_title[0] = "【複写中】";
	}
	else
	{
		MenuPosition( Menu( " 動作設定(&S)",
			"詳細表示	C",	ModeChange, CheckMode,
			"--------",		SEPARATE_MENU,
			"移動中止	ESC",	MenuQuit
			), Menu_Title );
		Status_title[0] = "【平行移動中】";
	}
	DrawStatus();
	quit_flag = FALSE;

	org = Cursor();
	while( TRUE )
	{
		temp = _MakeVector( org, ON );
		if( temp == -1 | temp == -2 )
		{
			PopandClear( OVERWRITE );
			return;
		}
		else
		{
			if( cur == org )
			{
				Warning();
				if( novice_flag == ON )
					Message( "２点目は移動量を指定してください" );
			}
			else
				break;
		}
	}
	Clear( OVERWRITE );
	vect = Position( cur ) - Position( org );
	if( flag == OFF )
	{
		mat = move( UNIT_MATRIX, vect );
		PolyMove( mat );
	}
	else
		Select( _CopyPolygons( vect ) );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}

//
//	面の複数コピー
//
function GridCopyPolygons()
{
	var	i, j, k, flag, kaisuu[3], check;
	var	msg[3];
	var	org, pos[3], temp, prev_sel, new_sel;
	var	org_vec, pos_vec[3], vect;

	msg[0] = "方向１";
	msg[1] = "方向２";
	msg[2] = "方向３";
	for( i = 0; i< 3; i++ )
		kaisuu[i] = 1;
	for( i = 0; i< 3; i++ )
		pos_vec[i] = vector( 0, 0, 0 );

	if ( SelectPolygons() == 0 )
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg3 );
		return ;
	}

	prev_sel = Select();
	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"複写中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【グリッド複写中】";
	DrawStatus();
	quit_flag = FALSE;

	flag = 0;
	org = Cursor();
	while( TRUE )
	{
		Cursor( org );
		temp = _MakeVector( org, OFF );
		if( temp == -1 )
		{
			PopandClear( OVERWRITE );
			return;
		}
		else if( temp == -2 )
		{
			if( flag == 0 )
			{
				PopandClear( OVERWRITE );
				return;
			}
			else if( flag == 1 )
			{
				flag--;
				DrawLine( org, pos[0] );
			}
			else
			{
				flag--;
				DrawLine( org, pos[1] );
			}
		}
		else
		{
			if( cur == org )
			{
				if( flag == 0 )
				{
					Warning();
					if( novice_flag == ON )
						Message( error_msg4 );
				}
				else
					break;
			}
			else
			{
				if( flag == 0 )
				{
					pos[0] = cur;
					flag++;
				}
				else if( flag == 1 )
				{
					if( pos[0] == cur )
					{
						Warning();
						if( novice_flag == ON )
							Message( error_msg4 );
						DrawLine( org, pos[0] );
					}
					else
					{
						pos[1] = cur;
						flag++;
					}
				}
				else if( flag == 2 )
				{
					if( pos[0] == cur )
					{
						Warning();
						if( novice_flag == ON )
							Message( error_msg4 );
						DrawLine( org, pos[0] );
					}
					else if( pos[1] == cur )
					{
						Warning();
						if( novice_flag == ON )
							Message( error_msg4 );
						DrawLine( org, pos[1] );
					}
					else
					{
						pos[2] = cur;
						flag++;
						break;
					}
				}
			}
		}
	}
	Clear( OVERWRITE );
	org_vec = Position( org );
	for( i = 0; i< flag;i++ )
		pos_vec[i] = Position( pos[i] ) - org_vec;

	while( TRUE )
	{
		check = ON;
		DlogOpen( "生成個数", flag*2+1 );
		for( i = 0; i< flag; i++ )
			DlogString( i*2, msg[i], "2", 6 );
		if( DlogWait() )
		{
			for( i = 0; i< flag; i++ )
			{
				kaisuu[i] = atoi( DlogAnswer( i*2 ) );
				if( kaisuu[i] == 0 )
				{
					Warning();
					check = OFF;
				}
			}
			if( check == ON )
				break;
		}
		else
		{
			PopandClear( OVERWRITE );
			return;
		}
	}

	SelectAll( FALSE );
	new_sel = Select();
	for( i = 0; i < kaisuu[2]; i++ )
	{
		for( j = 0; j < kaisuu[1]; j++ )
		{
			for( k = 0; k < kaisuu[0]; k++ )
			{
				if( !(( i == 0 ) & ( j == 0 ) & ( k == 0 )) )
				{
					vect = pos_vec[0]*k + pos_vec[1]*j + pos_vec[2]*i;
					Select( prev_sel );
					new_sel = new_sel | _CopyPolygons( vect );
				}
			}
		}
	}
	Select( new_sel );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}

//
//	ミラー複写（移動）
//
function Mirr()
{
	var sel, test, mat, vers, temp, rot_mat, key, i;
	var msg0[2], msg1[4];
	var mode_select, plane_select;
	var prev, point[3];
	var p0_vec, p1_vec, p2_vec, temp_vec;
	var pick, draw_flag = ON;

	if( SelectPolygons() == 0 )
	{
		Warning();
		if( novice_flag == ON )
			Message( error_msg3 );
		return;
	}

	PushMenu();
	Status_org = Status_title;
	MenuPosition( Menu( " 動作設定(&S)",
			"複写中止	ESC",	MenuQuit
		), Menu_Title );
	ClearStatus();
	Status_title[0] = "【ミラー複写・移動中】";
	DrawStatus();

	quit_flag = FALSE;

	sel = Select();
	DlogOpen( " ミラー複写・移動", 4 );
	msg0[0] = "  移動  ";
	msg0[1] = "  複写  ";
	DlogSelect( 1, "移動・複写選択", msg0, 1 );
	msg1[0] = "ＸＹ平面";
	msg1[1] = "ＹＺ平面";
	msg1[2] = "ＺＸ平面";
	msg1[3] = "自由平面";
	DlogSelect( 3, "   反転平面   ", msg1, 2 );

	if( DlogWait() )
	{
		mode_select = DlogAnswer( 1 );
		plane_select = DlogAnswer( 3 );
	}
	else
	{
		PopMenu();
		StatusBar(statustext);
		return;
	}

	if( mode_select == 1 )
		Select(_CopyPolygons( vector( 0,0,0)));

	if( plane_select == 3 )
	{
		vers = 0 ;
		cur = Cursor();
		pick = cur;
		input_flag = OFF;
		while( TRUE )
		{
			if( draw_flag == ON )
			{
				if( vers != 0 )
					DrawLine( cur, prev );
			}
			key = WaitEvent();
			if( key )
				input_flag = ON;
			if( (( ShiftStat() & 1 ) == 1 )& ( vers != 0 ))
			{
				cur = Cursor();
				TrimCursor(prev, MouseWindow());
				Cursor( cur );
			}
			else
				cur = Cursor();
			key = KeyCode();
			if ( input_flag | key == INPUT_KEY )
			{
				if( vers == 0 )
				{
					point[vers] = cur;
					prev = cur ;
					vers++;
				}
				else if( vers == 1 )
				{
					if( cur == point[0] )
					{
						Warning();
						if( novice_flag == ON )
							Message( error_msg4 );
					}
					else
					{
						point[vers] = cur;
						prev = cur ;
						vers++;
					}
				}
				else
				{
					if( cur == point[0] | cur == point[1] )
					{
						Warning();
						if( novice_flag == ON )
							Message( "反転する平面を指定してください" );
					}
					else
					{
						point[vers] = cur;
						vers++;
						prev = cur;
						break;
					}
				}
			}
			else if( key == ESC | quit_flag == TRUE )
			{
				PopandClear( OVERWRITE );
				return;
			}
			else if ( key == BS )
			{
				if ( vers > 1 )
				{
					if( cur != prev )
					{
						cur = point[vers-1];
						prev = point[vers - 2];
						cur = Cursor( cur );
						vers --;
						DrawLine( prev, cur );
					}
					else
					{
						prev = point[vers - 2];
						vers --;
						DrawLine( prev, cur );
					}
				}
				else if ( vers == 1 )
				{
					cur = point[vers-1];
					Cursor( cur );
					vers--;
				}
				else
				{
					PopandClear( OVERWRITE );
					return ;
				}
			}
			else
				temp = KeyProcess( key );
			if( ((key!=0 ) & (key != INPUT_KEY)) | ( pick != Cursor()) )
			{
				draw_flag = ON;
				if( vers != 0 )
					DrawLine( pick, prev );
			}
			else
				draw_flag = OFF;
			pick = Cursor();
			input_flag = OFF;
		}
		p0_vec = Position( point[0] );
		p1_vec = Position( point[1] );
		p2_vec = Position( point[2] );
		temp = move( UNIT_MATRIX, p1_vec*(-1) );
		p2_vec = p2_vec - p1_vec;
		p0_vec = p0_vec - p1_vec;
		if( abs(p2_vec.vector(1,0,0)) < 0.00001 )
		{
			temp_vec = p2_vec;
			p2_vec = p0_vec;
			p0_vec = temp_vec;
		}
		temp = move( UNIT_MATRIX, p1_vec*(-1) );
		rot_mat = vec( UNIT_MATRIX, p2_vec, p0_vec );
		mat = scale( UNIT_MATRIX, 1, -1, 1 );
		mat = ((temp/rot_mat)*mat*rot_mat)/temp;
	}
	else if( plane_select == 0 )
		mat = scale( UNIT_MATRIX, 1, 1, -1 );
	else if( plane_select == 1 )
		mat = scale( UNIT_MATRIX, -1, 1, 1 );
	else
		mat = scale( UNIT_MATRIX, 1, -1, 1 );
	Select( sel );
	PolyMove( mat );
	Update( CLEAR );
	UpdateObject();
	pers_rotation_flag = FALSE;
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
}
